using System;
using System.Collections.Generic;
using System.Text;
using System.Web;
using System.Web.Security;

namespace Acms.AcmsControls
{
    public class AcmsHttpModule : System.Web.IHttpModule
    {
        #region IHttpModule Members

        public void Dispose()
        {
        }

        public void Init(System.Web.HttpApplication context)
        {
            context.BeginRequest += new EventHandler(context_BeginRequest);
            context.AuthenticateRequest += new EventHandler(context_AuthenticateRequest);
        }

        void context_AuthenticateRequest(object sender, EventArgs e)
        {
            HttpApplication app = sender as HttpApplication;
            if (app != null)
            {
                HttpCookie cookie = app.Context.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (cookie != null)
                {
                    try
                    {
                        System.Web.Security.FormsAuthenticationTicket ticket = System.Web.Security.FormsAuthentication.Decrypt(cookie.Value);
                        if (ticket != null)
                        {
                            Guid key = Guid.Empty;
                            int siteId = 0;
                            try
                            {
                                key = new Guid(ticket.Name);
                            }
                            catch (FormatException)
                            {
                            }

                            try
                            {
                                siteId = int.Parse(ticket.UserData);
                            }
                            catch (FormatException)
                            {
                                Bll.Site tmp = Bll.Site.GetFromHttpRequest(app.Request);
                                if (tmp != null)
                                {
                                    siteId = tmp.Id;
                                }
                            }

                            if (key != Guid.Empty)
                            {
                                app.Context.User = Acms.Bll.UserPrinciple.Construct(key, siteId);
                            }
                        }
                    }
                    catch (System.Security.Cryptography.CryptographicException)
                    {
                    }
                }
                if (app.Context.User == null || !(app.Context.User is Acms.Bll.UserPrinciple))
                {
                    app.Context.User = Acms.Bll.UserPrinciple.Construct();
                }
            }
        }

        void context_BeginRequest(object sender, EventArgs e)
        {
            System.Web.HttpApplication app = sender as System.Web.HttpApplication;
            if (app != null)
            {
                string path = app.Context.Request.AppRelativeCurrentExecutionFilePath;

                //only intercept relevant files
                bool intercept = false;
                //if aspx page intercept
                if (path.ToLower().EndsWith(".aspx"))
                    intercept = true;
                //unless if the file actually exists and it is not just a default page.
                if (System.IO.File.Exists(app.Context.Server.MapPath(path)) && !path.ToLower().EndsWith("/default.aspx"))
                    intercept = false;
                //if acms dont intercept
                if (path.ToLower().StartsWith("~/acms/") || app.Context.Request.ApplicationPath.ToLower().EndsWith("/acms"))
                    intercept = false;
                if (intercept)
                {
                    if (path.ToLower().EndsWith("/default.aspx"))
                    {
                        path = path.Remove(path.ToLower().IndexOf("/default.aspx"));
                    }
                    else if (path.IndexOf('.') > -1)
                    {
                        path = path.Remove(path.LastIndexOf("."));
                    }

                    string templateName = app.Context.Request.QueryString["TF"];
                    string postUrl = null;
                    string postCacheKey = string.Concat(path, templateName);

                    //try ToString get from cache
                    if (app.Context.Cache[postCacheKey] != null && app.Context.Cache[postCacheKey] is string)
                    {
                        postUrl = (string)app.Context.Cache[string.Concat(path, templateName)];
                    }
                    //if not from db
                    if (string.IsNullOrEmpty(postUrl))
                    {
                        string siteRoot = app.Context.Request.ServerVariables["Server_Name"];
                        if (app.Context.Request.ApplicationPath != "/")
                            siteRoot += app.Context.Request.ApplicationPath;
                        Acms.Bll.Post post = Acms.Bll.Post.GetBySiteUrlAndPostUrl(siteRoot, path);
                        if (post != null)
                        {
                            Acms.Bll.TemplateFile templateFile = null;
                            if (!string.IsNullOrEmpty(templateName))
                            {
                                templateFile = post.GetFile(templateName);
                                if (templateFile == null)
                                {
                                    throw new Acms.Exceptions.TemplateException(string.Format("Could not load template file '{0}' for post '{1}' template '{2}'", templateName, post.Path, post.TemplateName));
                                }
                            }
                            else
                            {
                                templateFile = post.GetDefaultFile();
                                if (templateFile == null)
                                {
                                    throw new Acms.Exceptions.TemplateException(string.Format("Could not load template file '{0}' for post '{1}' template '{2}'", templateName, post.Path, post.TemplateName));
                                }
                            }
                            if (templateFile.Path.ToLower().EndsWith(".ascx"))
                            {
                                postUrl = string.Concat("~/LoadTemplate.aspx?", post.GetQueryString(templateFile));
                            }
                            else
                            {
                                postUrl = string.Concat(templateFile.Path, templateFile.Path.Contains("?") ? "&" : "?", "AcmsPostId=", post.Id, "&AcmsSiteId=", post.SiteId);
                            }
                            app.Context.Cache.Insert(postCacheKey, postUrl, null, DateTime.Now.AddHours(1), TimeSpan.Zero, System.Web.Caching.CacheItemPriority.BelowNormal, null);
                        }
                        else
                        {
                            throw new Exception(string.Format("Could not find '{0} '{1}'", siteRoot, path));
                        }
                    }

                    if (!string.IsNullOrEmpty(postUrl))
                    {
                        if (app.Context.Request.QueryString.Keys.Count > 0)
                        {
                            postUrl = string.Concat(postUrl, "&", app.Context.Request.QueryString.ToString());
                        }
                        app.Context.RewritePath(postUrl.Substring(0, postUrl.IndexOf('?')), null, postUrl.Substring(postUrl.IndexOf('?') + 1), false);
                    }
                }
            }
        }

        #endregion
    }
}
